package com.ganeshkrishnan.globald.dao.hibernate;

import java.util.List;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ganeshkrishnan.globald.abstracts.GenericDaoHibernate;
import com.ganeshkrishnan.globald.dao.PersonLocationDao;
import com.ganeshkrishnan.globald.model.PersonLocation;

@Repository
@Transactional
public class PersonLocationDaoHibernate extends GenericDaoHibernate<PersonLocation, Long> implements PersonLocationDao {
	public PersonLocationDaoHibernate() {
		super(PersonLocation.class);
	}

	@SuppressWarnings("unchecked")
	public PersonLocation findHomeCityByPersonID(Long PersonID) {
		List l = getHibernateTemplate().find("from PersonLocation where locationType=0 AND PersonID=?", PersonID);
		//FIXME edgecase array out of bounds if NO home city!
		if (null != l)
			return (PersonLocation) l.get(0);
		else
			return null;
	}

	@SuppressWarnings("unchecked")
	public List<PersonLocation> findSatellitesByPersonID(Long PersonID) {
		return getHibernateTemplate().find("from PersonLocation where locationType=1 AND PersonID=?", PersonID);
	}

	@SuppressWarnings("unchecked")
	public List<PersonLocation> findbyCords(float lat, float lon) {
		return getHibernateTemplate().find("from PersonLocation where latitude=" + lat + " AND longitude=?", lon);
	}

	@SuppressWarnings("unchecked")
	public List<PersonLocation> findNear(float lat, float lon, float precision) {
		return getHibernateTemplate().find(
				"from PersonLocation where (latitude>" + (lat - precision) + " AND latitude< " + (lat + precision)
						+ " )AND (longitude >" + (lon - precision) + " AND longitude< " + (lon + precision));
	}

	@SuppressWarnings("unchecked")
	public List<PersonLocation> findMyHomesNear(Long personID, float lat, float lon, float precision) {
		return getHibernateTemplate().find(
				"from PersonLocation where PersonID=" + personID + " AND (latitude>" + (lat - precision)
						+ " AND latitude< " + (lat + precision) + " )AND (longitude >" + (lon - precision)
						+ " AND longitude< " + (lon + precision));
	}

	@SuppressWarnings("unchecked")
	public List<PersonLocation> findMySatellitesbyBounds(Long personID, float nlat, float nlon, float slat, float slon) {
		return getHibernateTemplate().find(
				"from PersonLocation where locationType!=0 AND PersonID=" + personID + " AND (latitude >" + slat
						+ " AND latitude< " + nlat + ") AND (longitude> " + slon + " AND longitude< " + nlon + ")");
	}

	//FIXME filter out allies!!
	@SuppressWarnings("unchecked")
	public List<PersonLocation> findCombatantsbyBounds(Long personID, float nlat, float nlon, float slat, float slon) {
		return getHibernateTemplate().find(
				"from PersonLocation where PersonID!=" + personID + " AND locationType=2 AND (latitude >" + slat
						+ " AND latitude< " + nlat + ") AND (longitude> " + slon + " AND longitude< " + nlon + ")");
	}

	public List<Object[]> findTotalDeployed(Long personID) {
		String sql = "SELECT dep.resourceType, sum(dep.availResources)FROM PersonLocation P, Deployment dep where dep.personLocation=P.ID and P.person="
				+ personID + " group by resourceType order by P.ID";
		return runCustomQuery(sql);
	}

	@SuppressWarnings("unchecked")
	public List<PersonLocation> findCombatantsbyCountryBounds1(Long personID, float nlat, float nlon, float slat,
			float slon, int country) {
		return getHibernateTemplate().find(
				"from PersonLocation pl, Person P where pl.PersonID!=" + personID
						+ " AND pl.locationType=2 AND (pl.latitude >" + slat + " AND pl.latitude< " + nlat
						+ ") AND (pl.longitude> " + slon + " AND pl.longitude< " + nlon
						+ ") AND pl.PersonID=p.id AND p.countryCode!=" + country);
	}

	public List<Object[]> findCombatantsbyCountryBounds(Long personID, float nlat, float nlon, float slat, float slon,
			int country) {
		String sql = " Select pl.ID,pl.latitude,pl.longitude,p.firstName from PersonLocation pl, Person p where "
				+ "  pl.locationType=2 AND (pl.latitude >" + slat + " AND pl.latitude< " + nlat
				+ ") AND (pl.longitude> " + slon + " AND pl.longitude< " + nlon
				+ ") AND pl.person=p.id AND p.countryCode!=" + country;
		return runCustomQuery(sql);
	}
}
